package socket1;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;

public class Server {
    /**
     *java.net.ServerSocket
     *运行在服务器，作用有两个
     * 1、向系统申请服务端口，客户端通过该端口与服务端建立连接
     * 2、监听客户端的连接请求，一旦有客户端连接，则返回一个Socket对象，该Socket对象可以和客户端进行通信
     *   若将socket比作电话，ServerSocket则相当于客户中心的总机
     */
    private ServerSocket serverSocket;//创建服务器套接字

    private List<PrintWriter> allOut = new ArrayList<>();

    public Server(){
        try {
            System.out.println("服务器正在启动...");
            serverSocket = new ServerSocket(8080);
            System.out.println("服务器启动完毕");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void start(){
        try {
            System.out.println("等待客户端连接");
            while(true){

                Socket socket = serverSocket.accept();
                System.out.println("一个客户端连接了");
                /*InputStream input = socket.getInputStream();
                InputStreamReader isr = new InputStreamReader(input, StandardCharsets.UTF_8);
                BufferedReader br = new BufferedReader(isr);
                String str;
                while((str=br.readLine())!=null){
                    System.out.println(str);
                }*/
                Runnable handler = new ClientHandler(socket);
                Thread t = new Thread(handler);
                t.start();
            }

        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    public class ClientHandler implements Runnable{
        private Socket socket;
        private String host;
        private String nickname;
        public ClientHandler(Socket socket){
            this.socket=socket;
            host = socket.getInetAddress().getHostAddress();//获取客户端ip地址
        }

        public void run(){
            PrintWriter pw = null;
            try {
                InputStream input = socket.getInputStream();
                InputStreamReader isr = new InputStreamReader(input, StandardCharsets.UTF_8);
                BufferedReader br = new BufferedReader(isr);
                nickname = br.readLine();

                OutputStream out = socket.getOutputStream();
                OutputStreamWriter osw = new OutputStreamWriter(out,StandardCharsets.UTF_8);
                BufferedWriter bw = new BufferedWriter(osw);
                pw = new PrintWriter(bw,true);
                synchronized (allOut) {
                    allOut.add(pw);
                }

                broadcast(nickname+"["+host+"]"+"已上线，当前在线人数"+allOut.size());

                String messageFromClient;//获取来自客户端的信息
                while((messageFromClient=br.readLine())!=null){
                    broadcast(nickname+"["+host+"]"+messageFromClient);
                }


            } catch (IOException e) {

            } finally {
                synchronized (allOut) {
                    allOut.remove(pw);
                    //System.out.println(allOut);
                }
                broadcast(nickname+"["+host+"]"+"已下线，当前在线人数"+allOut.size());
                try {

                    socket.close();//四次挥手
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    public void broadcast(String str){
        System.out.println(str);
        synchronized (allOut) {
            for(PrintWriter o : allOut){
                o.println(str);
            }
        }
    }

    public static void main(String[] args){
        Server server = new Server();
        server.start();
    }




}
